﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Applee.FractCommon;
using System.Drawing;
using System.Windows.Forms;

namespace Applee.SierpinskiFract
{
    class Fract : IFractable, IDrawable
    {
        //protected FractPoints mPoints = new FractPoints();
        protected FractObjects mFractObjects = new FractObjects();

        #region IDrawable 成员

        public void OnPaint(System.Windows.Forms.PaintEventArgs pe)
        {
            foreach (IDrawable rf in mFractObjects)
            {
                rf.OnPaint(pe);
            }
        }

        #endregion

        #region IFractable 成员

        protected RandomColor mColorGen = new RandomColor();
        public RandomColor ColorGen
        {
            get { return mColorGen; }
            set { mColorGen = value; }
        }

        protected int mIterations = 0;
        public int Iterations
        {
            get { return mIterations; }
            set { mIterations = value; }
        }

        protected float mLength = 0;
        public float Length
        {
            get { return mLength; }
            set { mLength = value; }
        }

        protected Size mViewSize = new Size();
        public Size ViewSize
        {
            set { mViewSize = value; }
        }

        protected void CreateFract(PointF point, RandomColor color, float fLength, int iterations)
        {
            float[,] fData = new float[8, 6];
            for (int i = 0; i < 7; i++)
            {
                fData[i, 0] = 1.0F / 3;
                fData[i, 1] = 0;
                fData[i, 2] = 0;
                fData[i, 3] = 1.0F / 3;
            }

            float fMaxY = fLength;

            fData[0, 4] = 1;
            fData[0, 5] = 1;

            fData[1, 4] = fMaxY;
            fData[1, 5] = 1;

            fData[2, 4] = 1;
            fData[2, 5] = fMaxY;

            fData[3, 4] = fMaxY;
            fData[3, 5] = fMaxY / 1.0F; //{可尝试除以2, 3, 4}

            fData[4, 4] = fMaxY / 2.0F;
            fData[4, 5] = 1;

            fData[5, 4] = fMaxY;
            fData[5, 5] = fMaxY / 2.0F;

            fData[6, 4] = 1;
            fData[6, 5] = fMaxY / 2.0F;

            fData[7, 4] = fMaxY / 2.0F;
            fData[7, 5] = fMaxY;

            float X = 0;
            float Y = 0;

            Random r = new Random();
            
            for (int n = 0; n < Convert.ToInt32(fLength); n++ )
            {
                int k = r.Next(8);
                X = fData[k - 1, 0] * X + fData[k - 1, 1] * Y + fData[k - 1, 4];
                Y = fData[k - 1, 2] * X + fData[k - 1, 3] * Y + fData[k - 1, 5];

                FractPoint fp = new FractPoint();
                fp.MakeShape(new PointF(X, Y), 1.0F);
                fp.Color = color.GetColor(iterations);
                //mPoints.Add(fp);
            }
        }

        protected void Sier(float x1, float y1, float x2, float y2, int n)   
        {   
            float W,L;   
            if(n>1)   
            {   
                L=x2-x1;W=y2-y1;
   
                //dc.MoveTo(int(x1+L/3),int(y1+W/3));   
                //dc.Rectangle(CRect(int(x1+L/3),int(y1+W/3),int(x2-L/3),int(y2-W/3))); 

                //SierRectangle sr = new SierRectangle();
                //sr.MakeShape();

                Sier(x1,y1,x1+L/3,y1+W/3,n-1);   
                Sier(x1+L/3,y1,x2-L/3,y1+W/3,n-1);   
                Sier(x2-L/3,y1,x2,y1+W/3,n-1);   
                Sier(x1,y1+W/3,x1+L/3,y2-W/3,n-1);   
                Sier(x2-L/3,y1+W/3,x2,y2-W/3,n-1);   
                Sier(x1,y2-W/3,x1+L/3,y2,n-1);   
                Sier(x1+L/3,y2-W/3,x2-L/3,y2,n-1);   
                Sier(x2-L/3,y2-W/3,x2,y2,n-1);   
            }   
        } 

        public void CreateFract(float fLength, int iterations)
        {
            try
            {
                mLength = mViewSize.Height;
                RandomColor rc = new RandomColor();
                //CreateFract(new PointF(0, 0), rc, mLength, iterations);
                Sier(10, 10, 400, 400, iterations);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion
    }
}
